package com.cola.custSpeechTranscription.api;

import com.cola.custSpeechTranscription.config.CustWebSocketClientConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @BelongsProject: custSpeechTranscription
 * @BelongsPackage: com.cola.custSpeechTranscription.api
 * @Author: jiangkang
 * @CreateTime: 2025-10-30  14:59
 * @Description: TODO
 * @Version: 1.0
 */
public class CustRemoteWebSocketClient extends WebSocketClient {

    private static final Logger log = LoggerFactory.getLogger("LCAP_EXTENSION_LOGGER");

    private static final ObjectMapper MAPPER = new ObjectMapper();

    private final WebSocketSession frontEndSession;
    private boolean firstFrameSent = false;
    private final CustWebSocketClientConfig config;
    private final CustShareSessionManager shareSessionManager;
    private final String userId;

    public CustRemoteWebSocketClient(URI serverUri, WebSocketSession frontEndSession,
                                 CustWebSocketClientConfig config, CustShareSessionManager shareSessionManager,
                                 String userId) {
        super(serverUri);
        this.frontEndSession = frontEndSession;
        this.config = config;
        this.shareSessionManager = shareSessionManager;
        this.userId = userId;

//        // 设置请求头
//        String apid = config.getSpeechToTextApid();
//        String appId = config.getSpeechToTextAppId();
//        String secret = config.getSpeechToTextAppSecret();
//        String forwardedFor = config.getSpeechToTextForwardedFor();
//
//        String traceId = UUID.randomUUID().toString();
//        String timestamp = String.valueOf(System.currentTimeMillis());
//        String toSign = appId + secret + traceId + timestamp;
//        String sign = DigestUtils.md5Hex(toSign);
//        String sessionParam = generateSessionParam();
//
//        this.addHeader("apid", apid);
//        this.addHeader("appId", appId);
//        this.addHeader("apiCode", "ast");
//        this.addHeader("apiVersion", "1");
//        this.addHeader("traceId", traceId);
//        this.addHeader("timestamp", timestamp);
//        this.addHeader("sign", sign);
//        this.addHeader("sessionParam", sessionParam);
//        this.addHeader("x-forwarded-for", forwardedFor);
//        log.info("[WebSocket连接] userId={}, 请求头信息: traceId为{},时间戳为：{},sign为：{},sessionParam为：{}",
//                userId, traceId, timestamp, sign,sessionParam);

        //获取参数信息
        String speechTranscriptionAppId = config.getSpeechTranscriptionAppId();
        String speechTranscriptionAppKey = config.getSpeechTranscriptionAppKey();
        String speechTranscriptionApiPath = config.getSpeechTranscriptionApiPath();

        String uuid = UUID.randomUUID().toString().replace("-", "");
        String capabilityName=getCapabilityName(speechTranscriptionApiPath);
        //组成参数
        String csid = speechTranscriptionAppId + capabilityName + uuid;
        String str=  "{\"appid\":\"" + speechTranscriptionAppId + "\",\"csid\":\"" + csid + "\"}";
        String xServerParam = Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
        String xCurTime = System.currentTimeMillis() / 1000 + "";
        String xCheckSum = DigestUtils.md5Hex(speechTranscriptionAppKey + xCurTime + xServerParam);
        String generateSessionParamStr = generateSessionParam();
        this.addHeader("appKey",speechTranscriptionAppKey);
        this.addHeader("x-server-param", xServerParam);
        this.addHeader("x-curtime", xCurTime);
        this.addHeader("x-checksum", xCheckSum);
        this.addHeader("Trace-User", speechTranscriptionAppId);
        this.addHeader("Trace-Id",csid);
        this.addHeader("sessionParam", generateSessionParamStr);
        log.info("[WebSocket连接] userId={}, appkey:{},xServerParam:{},xCurTime：{},xCheckSum：{},Trace-Id为：{},sessionParam为：{}",userId,speechTranscriptionAppKey, xServerParam,xCurTime,xCheckSum,csid,generateSessionParamStr);

    }

    private String generateSessionParam() {
        String json = "{\"operType\":\"zhuanxie\",\"rate\":\"16k\",\"sourceLang\":\"zh\"}";
        String encoded = Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8));
        return encoded;
    }

    public String getCapabilityName( String apiPath) {
        String[] pathSplit = StringUtils.split(apiPath, "/");
        if (pathSplit.length == 2 && "v1".equals(pathSplit[0]) && "querycapabilities".equals(pathSplit[1])) {
            return null;
        }
        String capabilityName = "";
        if (pathSplit[0].length() < 24) {
            //capabilityName = org.apache.commons.lang.StringUtils.rightPad(pathSplit[0], 24, '0');
            capabilityName = StringUtils.rightPad(pathSplit[0], 24, '0');
        } else if (pathSplit[0].length() > 24) {
            capabilityName = pathSplit[0].substring(0, 24);
        }
        return capabilityName;
    }

    public void sendAudioFrame(byte[] rawAudio) {
        try {
            String jsonFlag = "{\"endFlag\":0}";
            byte[] fullMessage = buildMessage(jsonFlag, rawAudio);
            this.send(fullMessage);
            log.info("[发送音频] userId={} [{} bytes] endFlag=0，firstFrameSent={}",
                    userId, fullMessage.length, firstFrameSent);
            firstFrameSent = true;
        } catch (Exception e) {
            log.error("[发送音频] 异常 userId={}", userId, e);
        }
    }

    public void sendEndFrame() {
        try {
            String endJson = "{\"endFlag\":1}";
            byte[] message = buildMessage(endJson, new byte[0]);
            this.send(message);
            log.info("[发送结束帧] userId={} 成功，消息长度={} bytes", userId, message.length);
        } catch (Exception e) {
            log.error("[发送结束帧] 异常 userId={}", userId, e);
        }
    }

    public void sendHeartbeatFrame() {
        try {
            String endJson = "{\"endFlag\":0}";
//            byte[] message = buildMessage(endJson, new byte[0]);
            this.send(endJson);
            log.info("[发送心跳] 成功");
        } catch (Exception e) {
            log.error("[发送心跳] 异常", e);
        }
    }

    private byte[] buildMessage(String json, byte[] audio) {
        if (audio == null) audio = new byte[0];
        byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8);
        int jsonLen = jsonBytes.length;

        byte[] message = new byte[4 + jsonLen + audio.length];
        message[0] = (byte) (jsonLen & 0xff);
        message[1] = (byte) ((jsonLen >> 8) & 0xff);
        message[2] = (byte) ((jsonLen >> 16) & 0xff);
        message[3] = (byte) ((jsonLen >> 24) & 0xff);
        System.arraycopy(jsonBytes, 0, message, 4, jsonLen);
        System.arraycopy(audio, 0, message, 4 + jsonLen, audio.length);
        return message;
    }

    @Override
    public void onMessage(String message) {
        log.info("[接收结果] userId={} 收到下游返回消息：{}", userId, message);

        try {
            // 首先发送给原始请求用户
            if (frontEndSession.isOpen()) {
                frontEndSession.sendMessage(new TextMessage(message));
            }

            // 格式化消息用于分享
            String formattedMessage = formatMessageForSharing(message);

            // 保存到用户历史记录
            if (formattedMessage !=null){
                shareSessionManager.addTranscript(userId, formattedMessage);
            }
        } catch (IOException e) {
            log.error("[结果转发] 发送到前端失败 userId={}", userId, e);
        }
    }

    /**
     * 格式化消息用于分享
     */
    private String formatMessageForSharing(String originalMessage) {
        String str =null;
        JSONObject jsonMessage = new JSONObject(originalMessage);
        int errorCode = jsonMessage.getInt("errorCode");
        if (errorCode == 0) {
            // 提取result字段（它本身是一个JSON字符串）
            String resultStr = jsonMessage.getString("result");

            Map<String, Object> map = new HashMap<>();
            map.put("type","listen");
            map.put("msg",resultStr);
            try{
                str = MAPPER.writeValueAsString(map);
            }catch (Exception e){
                log.error("收到我听转换失败：{}",e);
            }
            return str;
//            JSONObject resultJson = new JSONObject(resultStr);
//
//            // 提取ansStr字段（它又是一个JSON对象）
//            JSONObject ansStr = resultJson.getJSONObject("ansStr");
//            String sourceInfo = ansStr.getString("sourceInfo"); // 原文
//            String targetInfo = ansStr.getString("targetInfo"); // 译文
//            String msgType = ansStr.getString("msgtype");       // 消息类型
//            boolean endFlag = resultJson.getBoolean("endFlag"); // 结束标志
//
//            if ("sentence".equals(msgType)){
//                return sourceInfo;
//            }
        }
        return null;
    }

    @Override
    public void onOpen(ServerHandshake handshakeData) {
        log.info("[下游连接] userId={} 成功建立连接", userId);
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        log.info("[下游断开] userId={} code={} reason={} remote={}", userId, code, reason, remote);
    }

    @Override
    public void onError(Exception ex) {
        log.error("[下游错误] userId={} 异常", userId, ex);
    }
}